﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Management;
using System.IO;
using System.Diagnostics;
using System.Configuration;
using Microsoft.Win32;
using System.Security.Cryptography;

namespace Tools
{
    public static class SoftRegisterTools
    {      
        public static void killMyself()
        {
            string bat = string.Format("@echo off \n ping -n 3 127.0.0.1 \n del {0}", System.Windows.Forms.Application.ExecutablePath);
            File.WriteAllText("killme.bat", bat);
            ProcessStartInfo psi = new ProcessStartInfo();
            psi.FileName = "killme.bat";
            psi.Arguments = "\"" + Environment.GetCommandLineArgs()[0] + "\"";
            psi.WindowStyle = ProcessWindowStyle.Hidden;
            Process.Start(psi);
            System.Environment.Exit(0);
            //Application.Exit();
        }
        public static bool meIsMe()
        {
            if (getSoftMD5().Substring(0, 1) == SoftMD5)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        public static string getMachineNum()
        {
            if (SoftMD5 == string.Empty)
            {
                SoftMD5 = getSoftMD5();
            }
            if (DiskVolume == string.Empty)
            {
                DiskVolume = getDiskVolume();
            }
            if (string.IsNullOrEmpty(CPUSerialNum))
            {
                CPUSerialNum = getCPUserialNum();
            }
            string strNum = SoftVersion + SoftMD5.Substring(0, 5) + CPUSerialNum.Substring(0, 5) + DiskVolume.Substring(0, 5);
            return strNum;//18个注册字符
        }
        public static bool toRegist(string cipher)
        {
            try
            {
                if (CryptionHelper.VerifySigned(getMachineNum(), cipher, PublicKey))
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception e)
            {
                LogHelper.WriteLog(e);
                return false;
            }
        }
        //public static void updateConfig(string name, string value)
        //{
        //    Configuration cfa = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
        //    cfa.AppSettings.Settings[name].Value = value;
        //    cfa.Save();
        //    ConfigurationManager.RefreshSection("appSettings");
        //}

/*//        //Using Setting
        //Add by LJH
        public static string InitRegedit(out string expireDate)
        {
            string res = "";
            expireDate = "";
            //*检查注册表 BFEBFBFF000206A7-20190112//
            string SericalNumber = Tools.RegSetting.ReadSetting("", "SerialNumber", "-1");
            if (SericalNumber == "-1")
            {
                res = "软件尚未注册，请注册软件！";
            }
            //* 比较CPUid /
            string CpuId = SericalNumber.Split('-')[0];
            string CpuIdThis = getMachineNum();
            if (CpuId != CpuIdThis)
            {
                res = "注册机器与本机不一致,请联系管理员！";
            }
            // 比较时间 /
            string NowDate = DateTime.Now.ToString("yyyyMMdd");
            string EndDate = SericalNumber.Split('-')[1];
            if (Convert.ToInt32(EndDate) - Convert.ToInt32(NowDate) < 0)
            {
                res = "软件试用已到期！";
            }
            DateTime dt = DateTime.ParseExact(EndDate, "yyyyMMdd", System.Globalization.CultureInfo.CurrentCulture);
            expireDate = dt.ToString("yyyy年MM月dd日");
            return res;
        }
        public static bool Verify(string regCode)
        {
            string PUBLIC_KEY = PublicKey;
            string MAC = getMachineNum();
            try
            {
                RSACryptoServiceProvider cryptor = new RSACryptoServiceProvider();
                cryptor.FromXmlString(PUBLIC_KEY);
                byte[] signedData = Convert.FromBase64String(regCode);

                bool today = cryptor.VerifyData(
                  Encoding.UTF8.GetBytes(String.Format("[{}][{}]", DateTime.Now.ToString("yyyy-MM-dd"))),
                  "SHA", signedData);
                bool machineToday = cryptor.VerifyData(
                  Encoding.UTF8.GetBytes(String.Format("[{}][{}]", MAC, DateTime.Now.ToString("yyyy-MM-dd"))),
                  "SHA", signedData);
                bool forever = cryptor.VerifyData(
                  Encoding.UTF8.GetBytes(String.Format("[{}][{}]", MAC, Environment.MachineName)),
                  "SHA", signedData);
                return today || machineToday || forever;
            }
            catch
            {
                return false;
            }
        }
        public static bool GetIsReg()
        {
            bool IsCheck = false;
            //RegistryKey regKey = Registry.CurrentUser.OpenSubKey("SOFTWARE", true).CreateSubKey("mySoftWare").CreateSubKey("Register.INI");
            //foreach (var item in regKey.GetSubKeyNames())
            //{
            //    if (item == softReg.GetRegisterNum())
            //    {
            //        IsCheck = true;
            //    }
            //}
            return IsCheck;
        }
        // 判断软件是否可用，拥有二十次的试用期，也可以换成天数,再写入注册表信息      
        public static bool GetUseInfo(ref int m_intUse)
        {
            m_intUse = 0;
            bool Is_CanUse = false;
            try
            {
                m_intUse = (int)Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\mySoftWare", "UseTimes", 0);
            }
            catch (Exception)
            {
                Registry.SetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\mySoftWare", "UseTimes", 0, RegistryValueKind.DWord);
            }
            m_intUse = (int)Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\mySoftWare", "UseTimes", 0);
            if (m_intUse < 5)
            {
                int int_count = m_intUse + 1;
                Registry.SetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\mySoftWare", "UseTimes", int_count);
                Is_CanUse = true;
            }
            else
            {
                Is_CanUse = false;
            }
            return Is_CanUse;
        }
//*/

        private static string SoftVersion = "V02";//v0.1
        private static string SoftMD5 = string.Empty;
        private static string DiskVolume = string.Empty;
        private static string CPUSerialNum = string.Empty;
        private static string PublicKey = "<RSAKeyValue><Modulus>kkrIPGLqt2CUSeSLC3l4lgJzLuBt0GGwTI7Jqt9SbHmj8Kaz5ffPbHY3aibx4jF8bmWlyNiO8LTc2qL6CV1mCL599mStYhIdePElE9+WxniSc3YCCzKxpTnWjRL7ROA25fQPJghAWUiWva7VamwjF0rLHDgX+rcuGF7LScY49B0=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";
        private static string getDiskVolume()
        {
            //ManagementClass mc = new ManagementClass("win32_NetworkAdapterConfiguration");
            ManagementObject disk = new ManagementObject("win32_logicaldisk.deviceid=\"c:\"");
            disk.Get();
            return disk.GetPropertyValue("VolumeSerialNumber").ToString();
        }
        private static string getCPUserialNum()
        {
            string strCpu = null;
            ManagementClass myCpu = new ManagementClass("win32_Processor");
            ManagementObjectCollection myCpuCollection = myCpu.GetInstances();
            foreach (ManagementObject myObject in myCpuCollection)
            {
                strCpu = myObject.Properties["Processorid"].Value.ToString();
            }
            return strCpu;
        }
        private static string getSoftMD5()
        {
            string fileName = System.Windows.Forms.Application.ExecutablePath;
            try
            {
                FileStream file = new FileStream(fileName, FileMode.Open, FileAccess.Read);
                System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
                byte[] retVal = md5.ComputeHash(file);
                file.Close();

                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < retVal.Length; i++)
                {
                    sb.Append(retVal[i].ToString("x2"));
                }
                return sb.ToString().ToUpper();
            }
            catch (Exception ex)
            {
                throw new Exception("GetMD5HashFromFile() fail,error:" + ex.Message);
            }
        }
    }
    public class CryptionHelper
    {
        public static bool VerifySigned(string machinecode, string cipher, string PublicKey)
        {
            throw new NotImplementedException();
        }
    }
    public class LogHelper
    {
        public static void WriteLog(Exception e)
        {
            File.AppendAllText("loginerror.log", System.DateTime.Now + " 登录失败，原因是：" + e.Message + "\r\n");
        }
    }
    
    public class RegSetting
    {
        public static void WriteSetting(string Section, string Key, string Setting) // name = key value=setting Section= path
        {
            string text1 = Section;
            RegistryKey key1 = Registry.CurrentUser.CreateSubKey("Software\\efwplusServer\\cdkey"); // .LocalMachine.CreateSubKey("Software\\mytest");
            if (key1 == null)
            {
                return;
            }
            try
            {
                key1.SetValue(Key, Setting);
            }
            catch (Exception exception1)
            {
                return;
            }
            finally
            {
                key1.Close();
            }
        }
        // 读取注册表       
        public static string ReadSetting(string Section, string Key, string Default)
        {
            RegistryKey registryKey = Registry.CurrentUser.OpenSubKey("Software\\MyServer\\cdkey");
            if (registryKey != null)
            {
                object objValue = registryKey.GetValue(Key, Default);

                if (objValue != null)
                {
                    //Default = Encryption.DisEncryPW(objValue.ToString(), Key); //key2
                }
                registryKey.Close();
            }
            return Default;
        }
    }
}